/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * Copyright (C) 2008 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using Galaxium.Core;

using Anculus.Core;

namespace Galaxium.Protocol
{
	public abstract class AbstractEntity: IEntity
	{
		public event EntityChangeEventHandler<string> DisplayNameChange;
		public event EntityChangeEventHandler<string> DisplayMessageChange;
		public event EntityChangeEventHandler<IDisplayImage> DisplayImageChange;
		public event EntityChangeEventHandler<IPresence> PresenceChange;
		public event EntityChangeEventHandler<string> NicknameChange;
		public event EntityChangeEventHandler<bool> SupressChange;
		
		protected bool _local;
		protected string _uniqueIdentifier;
		protected ISession _session;
		protected IPresence _presence;
		protected string _nickname;
		protected string _displayName;
		protected string _displayMessage;
		protected IDisplayImage _displayImage;
		protected bool _supressImage;
		protected bool _supressName;
		protected bool _supressMessage;
		
		public AbstractEntity(ISession session, bool local, string uid, string dispName, string nickname, string dispMsg, IDisplayImage dispImg, IPresence pres)
		{
			_local = local;
			_uniqueIdentifier = uid;
			_nickname = nickname;
			_displayName = dispName;
			_displayMessage = dispMsg;
			_displayImage = dispImg;
			_presence = pres;
			_session = session;
		}
		
		public AbstractEntity(ISession session, bool local, string uid, string dispName, string nickname, string dispMsg, IDisplayImage dispImg)
			: this(session, local, uid, dispName, nickname, dispMsg, dispImg, null)
		{
			
		}
		
		public AbstractEntity(ISession session, bool local, string uid, string dispName, string nickname, string dispMsg)
			: this(session, local, uid, dispName, nickname, dispMsg, null)
		{
			
		}
		
		public AbstractEntity(ISession session, bool local, string uid, string dispName, string nickname)
			: this(session, local, uid, dispName, nickname, string.Empty)
		{
			
		}
		
		public AbstractEntity(ISession session, bool local, string uid, string dispName)
			: this(session, local, uid, dispName, string.Empty)
		{
			
		}
		
		public AbstractEntity(ISession session, bool local, string uid)
			: this(session, local, uid, string.Empty)
		{
			
		}
		
		public bool Local
		{
			get { return _local; }
		}
		
		public virtual string UniqueIdentifier
		{
			get { return _uniqueIdentifier; }
		}

		public virtual ISession Session
		{
			get { return _session; }
			set
			{
				_session = value;
				OnSessionChange ();
			}
		}

		public virtual IPresence Presence
		{
			get { return _presence; }
			set
			{
				IPresence _oldpresence = _presence;
				_presence = value;
				
				if (_presence != _oldpresence)
				{
					this.OnPresenceChange(new EntityChangeEventArgs<IPresence>(this, _presence, _oldpresence));
				}
			}
		}
		
		public bool SupressImage
		{
			get { return _supressImage; }
			set
			{
				if (_supressImage != value) {
					EntityChangeEventArgs<bool> args = new EntityChangeEventArgs<bool>(this, value, _supressImage);
					_supressImage = value;
					OnSupressChange (args);
				}
			}
		}
		
		public bool SupressName
		{
			get { return _supressName; }
			set
			{
				if (_supressName != value) {
					EntityChangeEventArgs<bool> args = new EntityChangeEventArgs<bool>(this, value, _supressName);
					_supressName = value;
					OnSupressChange (args);
				}
			}
		}
		
		public bool SupressMessage
		{
			get { return _supressMessage; }
			set
			{
				if (_supressMessage != value) {
					EntityChangeEventArgs<bool> args = new EntityChangeEventArgs<bool>(this, value, _supressMessage);
					_supressMessage = value;
					OnSupressChange (args);
				}
			}
		}
		
		public string Nickname
		{
			get
			{
				if (String.IsNullOrEmpty (_nickname))
					return String.Empty;
				
				return _nickname;
			}
			set
			{
				if (_nickname != value) {
					EntityChangeEventArgs<string> args = new EntityChangeEventArgs<string>(this, value, _nickname);
					_nickname = value;
					OnNicknameChange (args);
				}
			}
		}
		
		public bool HasNickname
		{
			get { return (_nickname != null && _nickname.CompareTo(String.Empty) != 0); }
		}
		
		public string DisplayIdentifier
		{
			get
			{
				string identifier = String.Empty;
				
				if (Session != null)
				{
					IConfigurationSection config = Configuration.ContactList.Section;
					bool showNicknames = Session.Account.UseDefaultListView ? config.GetBool (Configuration.ContactList.ShowContactNicknames.Name, Configuration.ContactList.ShowContactNicknames.Default) : Session.Account.ShowNicknames;
					bool showDisplayNames = Session.Account.UseDefaultListView ? config.GetBool (Configuration.ContactList.ShowContactNames.Name, Configuration.ContactList.ShowContactNames.Default) : Session.Account.ShowDisplayNames;
					
					if (showNicknames && !String.IsNullOrEmpty(Nickname) && Nickname.Length > 0)
						identifier = Nickname;
					else if (showDisplayNames && !SupressName)
						identifier = DisplayName;
					else
						identifier = UniqueIdentifier;
				}
				else identifier = UniqueIdentifier;
				
				return identifier;
			}
		}
		
		public virtual string DisplayName
		{
			get
			{
				if (_displayName == null || _displayName == String.Empty)
					return UniqueIdentifier;
				
				return _displayName;
			}
			set
			{
				string _oldDisplayName = _displayName;
				_displayName = value;
				
				if (_displayName != _oldDisplayName)
				{
					//ActivityUtility.EmitActivity (this, new EntityNameChangeActivity(this, _oldDisplayName));
					this.OnDisplayNameChange(new EntityChangeEventArgs<string>(this, _displayName, _oldDisplayName));
				}
			}
		}
		
		public virtual void SetDisplayName (string displayName)
		{
			_displayName = displayName;
		}
		
		public virtual string DisplayMessage
		{
			get
			{
				if (SupressMessage) return String.Empty;
				else return _displayMessage;
			}
			set
			{
				string _oldDisplayMessage = _displayMessage;
				_displayMessage = value;
				
				if (_displayMessage != _oldDisplayMessage)
				{
					this.OnDisplayMessageChange(new EntityChangeEventArgs<string>(this, _displayMessage, _oldDisplayMessage));
				}
			}
		}

		public virtual IDisplayImage DisplayImage 
		{
			get { return _displayImage; }
			set
			{
				IDisplayImage _oldDisplayImage = _displayImage;
				_displayImage = value;
				
				if (_displayImage != _oldDisplayImage)
				{
					//ActivityUtility.EmitActivity (this, new EntityImageChangeActivity(this, _oldDisplayImage));
					this.OnDisplayImageChange(new EntityChangeEventArgs<IDisplayImage>(this, _displayImage, _oldDisplayImage));
				}
			}
		}
		
		protected virtual void OnPresenceChange(EntityChangeEventArgs<IPresence> args)
		{
			if (this.PresenceChange != null)
				this.PresenceChange(this, args);
		}
		
		protected virtual void OnNicknameChange (EntityChangeEventArgs<string> args)
		{
			if (NicknameChange != null)
				NicknameChange (this, args);
		}
		
		protected virtual void OnDisplayNameChange(EntityChangeEventArgs<string> args)
		{
			if (this.DisplayNameChange != null)
				this.DisplayNameChange(this, args);
		}
			    
		protected virtual void OnDisplayMessageChange(EntityChangeEventArgs<string> args)
		{
			if (this.DisplayMessageChange != null)
				this.DisplayMessageChange(this, args);
		}
		
		protected virtual void OnDisplayImageChange(EntityChangeEventArgs<IDisplayImage> args)
		{
			if (this.DisplayImageChange != null)
				this.DisplayImageChange(this, args);
		}
		
		protected virtual void OnSupressChange (EntityChangeEventArgs<bool> args)
		{
			if (SupressChange != null)
				SupressChange (this, args);
		}
		
		protected virtual void OnSessionChange ()
		{
			
		}
		
		public void EmitPresenceChange (EntityChangeEventArgs <IPresence> args)
		{
			OnPresenceChange(args);
		}
	}
}
